package me.softwareengineer.guice.rendering.domain;

import java.util.List;
import java.util.Map;

import me.softwareengineer.guice.rendering.listener.EndFormatEvent;
import me.softwareengineer.guice.rendering.listener.Listener;
import me.softwareengineer.guice.rendering.listener.StartFormatEvent;
import me.softwareengineer.guice.rendering.util.CollectionUtil;

/**
 * Represents a a sequence of in-line elements
 * having the specified formatting parameters.
 * 
 * 
 * <pre>
 * This class is thread-safe and can be cached/re-used and used concurrently.
 * </pre>
 * 
 * @author yadtahir
 * @since 1.0
 * @see Format
 * 
 */
//This class is marked as final as we want to make it immutable as much as possible
public final class FormatElement extends Element {
	/**
	 * Format style of the children
	 */
	private final Format style;

	/**
	 * Creates a format element with no properties
	 * 
	 * @param children
	 *            the children which the style will apply
	 * @param style
	 *            the format type
	 */
	public FormatElement(List<Element> children, Format style) {
		this(children, style, CollectionUtil.getEmptyProperties());
	}

	/**
	 * Constructs a format element with the provided properties. 
	 * @param children
	 * 			the children element which the style will apply
	 * @param style
	 * 			the format type
	 * @param properties 
	 * 			the properties of the format element. For more info, please check {@link HasProperties}
	 */
	public FormatElement(List<Element> children, Format style,
			Map<String, String> properties) {
		super(children, properties);
		this.style = style;
	}


	/**
	 * {@inheritDoc}
	 * 
	 * This class generates the following event:
	 * <ul>
	 * 	<li>@{EndFormatEvent}</li>
	 * </ul>
	 * @see EndFormatEvent
	 */
	@Override
	public void afterElement(Listener listener) {
		EndFormatEvent e = new EndFormatEvent(style, getAllProperties());
		listener.onEvent(e);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * This class generates the following event:
	 * <ul>
	 * 	<li>@{StartFormatEvent}</li>
	 * </ul>
	 * @see StartFormatEvent
	 */
	@Override
	public void beforeElement(Listener listener) {
		StartFormatEvent e = new StartFormatEvent(style, getAllProperties());
		listener.onEvent(e);
	}

	/**
	 * @return the format which be applied to the children elements
	 * 
	 * <p>
	 * This property is immutable and thread-safe
	 * </p>
	 */
	public Format getStyle() {
		
			return style;
		
	}

}
